import pyttsx3
import requests
import json
import queue
import threading
from typing import Generator

# 全局队列用于存储待朗读的内容
speech_queue = queue.Queue()
stop_event = threading.Event()

def talk_worker():
    """语音朗读工作线程"""
    engine = pyttsx3.init()
    engine.setProperty('rate', 160)
    
    while not stop_event.is_set():
        try:
            content = speech_queue.get(timeout=1)  # 等待1秒，避免无限阻塞
            if content:
                engine.say(content)
                engine.runAndWait()
        except queue.Empty:
            continue
        except Exception as e:
            print(f"语音朗读出错: {e}")

# 启动语音朗读线程
speech_thread = threading.Thread(target=talk_worker, daemon=True)
speech_thread.start()

def talkContent(content):
    """将内容放入朗读队列"""
    if content.strip():  # 避免朗读空内容
        speech_queue.put(content)

# Ollama API 地址
OLLAMA_API_URL = "http://localhost:11434"
MODEL_NAME = "deepseek-r1-lvkong-v2"

# SerpAPI 密钥
SERPAPI_KEY = "your_serpapi_key_here"

# 系统提示
SYSTEM = """
你是一个严谨的AI助手，必须用中文回答问题。
你的回答必须详细，准确，并且遵循以下格式：
User: [用户输入]
Assistant: [你的回答]
如果用户的问题不明确，请要求用户提供更多信息。
如果问题需要实时信息，请使用联网搜索功能获取最新数据。
"""

def build_prompt(system_prompt, user_input, search_results=None):
    prompt = f"""<|system|>
{system_prompt}<|end|>
<|user|>
User: {user_input}<|end|>
<|assistant|>
Assistant:"""
    if search_results:
        prompt += f"\n以下是根据你的问题搜索到的实时信息：\n{search_results}\n"
    return prompt

def search_web(query, api_key):
    """调用 SerpAPI 进行联网搜索"""
    url = "https://serpapi.com/search"
    params = {
        "q": query,
        "api_key": api_key
    }
    try:
        response = requests.get(url, params=params, timeout=10)
        if response.status_code == 200:
            return response.json()
        else:
            print(f"搜索失败，状态码：{response.status_code}")
            return None
    except requests.exceptions.RequestException as e:
        print(f"搜索请求发生错误：{e}")
        return None

def get_deepseek_response(user_input) -> Generator[str, None, None]:
    if user_input.lower() in ["退出", "结束"]:
        talkContent("感谢使用！")
        return

    # 判断是否需要联网搜索
    need_search = any(keyword in user_input for keyword in ["最新", "实时", "今天"])
    search_results = None
    if need_search:
        print("正在联网搜索...")
        search_data = search_web(user_input, SERPAPI_KEY)
        if search_data:
            search_results = search_data.get("organic_results", [])
            search_results = "\n".join([f"{result['title']}: {result['link']}" for result in search_results[:3]])

    data = {
        "model": MODEL_NAME,
        "prompt": build_prompt(SYSTEM, user_input, search_results),
        "stream": True
    }

    try:
        response = requests.post(f"{OLLAMA_API_URL}/api/generate", json=data, timeout=30, stream=True)

        if response.status_code == 200:
            full_response = ""
            for line in response.iter_lines():
                if line:
                    chunk = line.decode("utf-8")
                    json_data = json.loads(chunk)

                    if "response" in json_data:
                        response_text = json_data["response"]
                        full_response += response_text
                        yield response_text

                    if json_data.get("done", False):
                        # 将完整响应放入朗读队列
                        if full_response.strip():
                            talkContent(full_response)
                        break

            yield "\n"
        else:
            error_msg = f"请求失败，状态码：{response.status_code}"
            print(error_msg)
            talkContent(error_msg)
            print("API 返回：", response.text)
    except requests.exceptions.Timeout:
        error_msg = "请求超时，请检查网络或 API 服务是否正常。"
        print(error_msg)

        
        talkContent(error_msg)
    except requests.exceptions.RequestException as e:
        error_msg = f"请求发生错误：{e}"
        print(error_msg)
        talkContent(error_msg)

# if __name__ == '__main__':
#     try:
#         while True:
#             input_text = input("请输入问题：")
#             if not input_text.strip():
#                 talkContent("deepseek回复：拜拜拜拜")
#                 break
            
#             print("DeepSeek回复：", end="", flush=True)
#             for response in get_deepseek_response(input_text):
#                 print(response, end="", flush=True)
#             print()  # 换行
#     finally:
#         # 清理工作
#         stop_event.set()
#         speech_thread.join()